/**
 * 解析路由
 */
import errorCatch from '../tools/errorCatch';
import controRoute from './controRoute';
import controConfig from '../../init/controConfig';
import { parsPlug } from "../../entrance/plug";
import Middleware from '../middleware/middleware';
import RequestType from '../../model/RequestType';


//解析路由
export {init as start, run_rout, mergeRout};

if(module) module.exports = { start:init, run_rout, mergeRout };
export default { start:init, run_rout, mergeRout }

//初始化路由
async function init(){
    // 给全局中间件赋值
    controRoute.setGlobalMiddleware(controConfig.getGlobal_Middleware())

    // 解析并设置全局中间件
    for(let key in controConfig.getrouteConfig()){
      let file:string   = (controConfig.getrouteConfig(key) as routeFile).path;
      if(!file){
        console.log("路由文件路径不可为空");
        continue;
      }
      //运行路由文件
      await run_rout(file);
    }

    //合并路由文件的内容
    await mergeRout();

    // 解析特殊接口
    await special(controConfig.getSpecial() as speciaConfig);
    // 解析扩展
    parsPlug()
}

//运行一个路由文件
async function run_rout(filepath:string){
  try{
    //执行路由文件
    await global.loader(filepath,true);
  }catch(err){
    errorCatch(err)
  }
}

//合并路由文件
async function mergeRout (){
  controRoute.setStaticRoute(Object_merge(controRoute.getUnStaticRoute() as unrouteStructure));
  controRoute.setDynamicRoute(Object_merge(controRoute.getUnDynamicRoute() as unrouteStructure));
}


//合并两个对象，内容相同合并，不同则添加
function Object_merge(objarr:unrouteStructure) :routeStructure{
  // 创建 get post any
  let obj:routeStructure = new RequestType();
  Object.keys(objarr).forEach(filepath=>{
    Object.keys(objarr[filepath]).forEach(type=>{
      Object.keys(objarr[filepath][type]).forEach(url=>{
        // get post any 都合并起来
        obj[type][url] = objarr[filepath][type][url];
      })
    })
  })
  return obj;
}


// 解析特殊接口
export async function special(specialConfig:speciaConfig){
  // 解析方法
  let pars = async (name:string,mes:string)=>{
    // 先判断下用户代码上有没有设置特殊接口
    if(!controRoute.getSpecialRoute(name)){
      // 默认配置中有这些接口的配置 用户的配置会覆盖默认的配置
      let inter:specialInter = controConfig.getSpecial(name) as specialInter;
      let controller = Middleware.pars_string_middleware(inter.path,name,inter.parameter || [])
      controRoute.addSpecialRoute(name,{
        modules:[],
        controller:controller
      })
    }
  }

  // 初始化特殊接口 如果用户自定义了特殊接口，那就不做更改 ，如果没有自定义，那就设置默认的接口
  for(let name in specialConfig){
    await pars(name,name+" 未设置路由");
  }
}
